﻿namespace ScrumFactory.Composition
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;


    

    [Export(typeof(IEventAggregator))]
    public class EventAggregator : IEventAggregator
    {

        

        private Dictionary<string, List<Action<object>>> events = new Dictionary<string, List<Action<object>>>();

        private Dictionary<string, List<Action>> eventsNoData = new Dictionary<string, List<Action>>();

        

        public void Subscribe<TData>(ScrumFactoryEvent e, Action<TData> action) {
            Subscribe<TData>(e.ToString(), action);
        }

        public void Subscribe(ScrumFactoryEvent e, Action action) {
            Subscribe(e.ToString(), action);
        }

      
        
        public void Subscribe<TData>(string eventName, Action<TData> action)
        {
            if (!events.ContainsKey(eventName))
            {
                events[eventName] = new List<Action<object>>();
            }

            var namedEvent = events[eventName];

            namedEvent.Add(d => { action((TData)d); });
        }

        public void Subscribe(string eventName, Action action) {
            if (!eventsNoData.ContainsKey(eventName)) {
                eventsNoData[eventName] = new List<Action>();
            }

            var namedEvent = eventsNoData[eventName];

            namedEvent.Add(action);
        }

        public void Publish<TData>(ScrumFactoryEvent e, TData data) {
            Publish<TData>(e.ToString(), data);
        }

        public void Publish(ScrumFactoryEvent e) {
            Publish(e.ToString());
        }

        public void Publish<TData>(string eventName, TData data)
        {
            if (events.ContainsKey(eventName))
            {
                events[eventName].ForEach(d => d(data));
            }
        }

        public void Publish(string eventName) {
            if (eventsNoData.ContainsKey(eventName)) {
                eventsNoData[eventName].ForEach(d => d());
            }
        }


        
    }

}
